package com.shanzmoo.admin.manager.store;

import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.shanzmoo.admin.domain.dto.*;
import com.shanzmoo.base.constant.e.BillOperateTypeEnum;
import com.shanzmoo.base.constant.e.SysBillTypeEnum;
import com.shanzmoo.base.exception.StoreException;
import com.shanzmoo.core.cache.CurrentUserCache;
import com.shanzmoo.core.manager.CodeManager;
import com.shanzmoo.db.store.entity.StorePurchaseBillDetailEntity;
import com.shanzmoo.db.store.entity.StorePurchaseBillEntity;
import com.shanzmoo.db.store.entity.StoreStockInitBillDetailEntity;
import com.shanzmoo.db.store.entity.bo.StoreReceiveSkuSelectBO;
import com.shanzmoo.db.store.entity.query.StorePurchaseBillQuery;
import com.shanzmoo.db.store.entity.vo.StorePurchaseBillDetailVO;
import com.shanzmoo.db.store.entity.vo.StorePurchaseBillVO;
import com.shanzmoo.base.bean.PageRespBase;
import com.shanzmoo.db.store.service.IStorePurchaseBillDetailService;
import com.shanzmoo.db.store.service.IStorePurchaseBillService;
import com.shanzmoo.db.store.service.IStoreStockInitBillDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 仓库采购单 管理器
 *
 * @author xueqz 2021-03-07
 */
@Slf4j
@Component
public class StorePurchaseBillManager {

    @Autowired
    private IStorePurchaseBillService storePurchaseBillService;

    @Autowired
    private IStorePurchaseBillDetailService storePurchaseBillDetailService;

    @Autowired
    private CodeManager codeManager;

    /**
     * 分页查询
     */
    public PageRespBase<StorePurchaseBillVO> queryPage(StorePurchaseBillQuery query) {
        Page page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<StorePurchaseBillVO> reList = storePurchaseBillService.queryPageList(query);

        if (CollUtil.isNotEmpty(reList)) {
            List<Integer> billIds = reList.stream().map(StorePurchaseBillVO::getId).collect(Collectors.toList());
            List<StorePurchaseBillDetailVO> detailAllList = storePurchaseBillDetailService.queryByBillIds(billIds);

            for (StorePurchaseBillVO billVO : reList) {
                List<StorePurchaseBillDetailVO> details = detailAllList.stream()
                        .filter(e -> billVO.getId().equals(e.getBillId()))
                        .collect(Collectors.toList());
                billVO.setDetail(details);
            }
        }

        PageRespBase<StorePurchaseBillVO> result = PageRespBase.create(page, reList);
        PageHelper.clearPage();
        return result;
    }

    @Transactional(rollbackFor = Throwable.class)
    public void add(BillSaveDto saveDto) {
        StorePurchaseBillSaveDTO storePurchaseBillSaveDTO = saveDto.getStorePurchaseBillSaveDTO();
        StorePurchaseBillEntity storePurchaseBillEntity = storePurchaseBillSaveDTO.convertEntity();
        List<StorePurchaseBillDetailEntity> list = new ArrayList<>();
        List<StorePurchaseBillDetailSaveDTO> billDetailSaveDTOList = saveDto.getBillDetailSaveDTOList();
        for (StorePurchaseBillDetailSaveDTO detailSaveDTO : billDetailSaveDTOList) {
            StorePurchaseBillDetailEntity billDetailEntity = detailSaveDTO.convertEntity();
            list.add(billDetailEntity);
        }
        storePurchaseBillEntity.setCreateUser(CurrentUserCache.getUserId());
        storePurchaseBillEntity.setBillNo(codeManager.generateBillNo(SysBillTypeEnum.PURCHASE_BILL));
        storePurchaseBillService.save(storePurchaseBillEntity);
        list.stream().forEach(r -> {
            r.setBillId(storePurchaseBillEntity.getId());
            r.setCreateUser(CurrentUserCache.getUserId());
        });
        storePurchaseBillDetailService.saveBatch(list);
    }

    @Transactional(rollbackFor = Throwable.class)
    public void update(BillUpdateDto updateDto) {
        StorePurchaseBillUpdateDTO storePurchaseBillUpdateDTO = updateDto.getStorePurchaseBillUpdateDTO();
        StorePurchaseBillEntity storePurchaseBillEntity = storePurchaseBillUpdateDTO.convertEntity();
        List<StorePurchaseBillDetailEntity> list = new ArrayList<>();
        List<StorePurchaseBillDetailUpdateDTO> billDetailSaveDTOList = updateDto.getBillDetailUpdateDTOList();
        for (StorePurchaseBillDetailUpdateDTO detailSaveDTO : billDetailSaveDTOList) {
            StorePurchaseBillDetailEntity billDetailEntity = detailSaveDTO.convertEntity();
            list.add(billDetailEntity);
        }
        storePurchaseBillService.updateById(storePurchaseBillEntity);
        //删除
        storePurchaseBillDetailService.deleteByBillId(storePurchaseBillEntity.getId());
        list.stream().forEach(r -> {
            r.setBillId(storePurchaseBillEntity.getId());
            r.setCreateUser(CurrentUserCache.getUserId());
        });
        storePurchaseBillDetailService.saveBatch(list);

    }

    public void operateBillStatus(BillOperateDto billOperateDto) {
        StorePurchaseBillEntity billEntity = storePurchaseBillService.getById(billOperateDto.getId());
        StorePurchaseBillEntity updateEntity = new StorePurchaseBillEntity();
        updateEntity.setId(billEntity.getId());
        if (BillOperateTypeEnum.AUDIT.getCode().equals(billOperateDto.getType())) {
            //审核
            if (billEntity.getStatus() != 0) {
                throw new StoreException("库存审核操作状态异常");
            }
            updateEntity.setStatus(1);
            updateEntity.setExamineUser(CurrentUserCache.getUserId());
            updateEntity.setExamineTime(LocalDateTime.now());

        } else if (BillOperateTypeEnum.CANCEL.getCode().equals(billOperateDto.getType())) {
            //取消
            if (billEntity.getStatus() != 0) {
                throw new StoreException("库存取消操作状态异常");
            }
            updateEntity.setStatus(9);

        } else if (BillOperateTypeEnum.RECEIVED.getCode().equals(billOperateDto.getType())) {
            //收货
            //todo 可以收货校验
            if (billEntity.getStatus() != 1) {
                throw new StoreException("库存收货操作状态异常");
            }
            updateEntity.setStatus(9);
            Boolean mark = Boolean.TRUE;

            List<StorePurchaseBillDetailEntity> detailList= storePurchaseBillDetailService.lambdaQuery()
                    .eq(StorePurchaseBillDetailEntity::getDeleted, false)
                    .eq(StorePurchaseBillDetailEntity::getBillId, billEntity.getId())
                    .list();
            for (StorePurchaseBillDetailEntity detailEntity : detailList) {
                if (!detailEntity.getPurchaseNum().equals(detailEntity.getReceiveNum())) {
                    //收货数量异常
                    mark = Boolean.FALSE;
                    break;
                }
            }
            updateEntity.setStatus(mark ? 3 : 2);
        } else {
            throw new StoreException("库存操作类型异常");
        }
        storePurchaseBillService.updateById(updateEntity);

    }

    public List<StoreReceiveSkuSelectBO> getReceiveList(String originOrder) {
        return storePurchaseBillService.getReceiveList(originOrder);
    }
}
